"""
插件管理器
负责插件的加载、注册、管理和生命周期控制
"""

import os
import importlib.util
import json
import asyncio
from typing import Dict, List, Type, Any
from .base_plugin import BasePlugin
from .data_source_plugin import DataSourcePlugin
from .processor_plugin import ProcessorPlugin
from .storage_plugin import StoragePlugin
import logging

logger = logging.getLogger(__name__)


class PluginManager:
    """插件管理器"""
    
    def __init__(self):
        self.plugins: Dict[str, BasePlugin] = {}
        self.plugin_registry: Dict[str, Type[BasePlugin]] = {}
        self.plugin_configs: Dict[str, Dict[str, Any]] = {}
    
    async def load_plugins(self, plugin_dir: str):
        """加载插件目录中的所有插件"""
        if not os.path.exists(plugin_dir):
            logger.warning(f"插件目录不存在: {plugin_dir}")
            return
        
        # 遍历插件目录中的所有子目录
        for root, dirs, files in os.walk(plugin_dir):
            for file in files:
                if file.endswith(".py") and not file.startswith("__"):
                    file_path = os.path.join(root, file)
                    await self.load_plugin_from_file(file_path)
    
    async def load_plugin_from_file(self, file_path: str):
        """从文件加载插件"""
        try:
            spec = importlib.util.spec_from_file_location("plugin_module", file_path)
            module = importlib.util.module_from_spec(spec)
            spec.loader.exec_module(module)
            
            # 查找插件类
            for attr_name in dir(module):
                attr = getattr(module, attr_name)
                if (isinstance(attr, type) and 
                    issubclass(attr, BasePlugin) and 
                    attr != BasePlugin and
                    attr != DataSourcePlugin and
                    attr != ProcessorPlugin and
                    attr != StoragePlugin):
                    plugin_class = attr
                    plugin_config = self._load_plugin_config(file_path)
                    plugin_instance = plugin_class(plugin_config)
                    
                    if await plugin_instance.initialize():
                        self.plugins[plugin_instance.name] = plugin_instance
                        self.plugin_registry[plugin_instance.name] = plugin_class
                        logger.info(f"成功加载插件: {plugin_instance.name}")
                    else:
                        logger.error(f"插件初始化失败: {plugin_instance.name}")
        except Exception as e:
            logger.error(f"加载插件失败 {file_path}: {e}")
    
    def _load_plugin_config(self, file_path: str) -> Dict[str, Any]:
        """加载插件配置"""
        config_path = file_path.replace(".py", ".json")
        if os.path.exists(config_path):
            try:
                with open(config_path, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except Exception as e:
                logger.warning(f"加载插件配置失败 {config_path}: {e}")
        
        # 返回默认配置
        return {
            "name": os.path.basename(file_path).replace(".py", ""),
            "version": "1.0.0",
            "enabled": True
        }
    
    async def execute_plugin_chain(self, plugin_names: List[str], initial_data: Dict[str, Any]) -> Dict[str, Any]:
        """执行插件链"""
        data = initial_data
        for plugin_name in plugin_names:
            if plugin_name in self.plugins and self.plugins[plugin_name].enabled:
                try:
                    data = await self.plugins[plugin_name].execute(data)
                except Exception as e:
                    logger.error(f"执行插件失败 {plugin_name}: {e}")
                    # 可以选择继续执行下一个插件或中断
                    # 这里我们选择继续执行
        return data
    
    async def get_plugin_info(self, plugin_name: str = None) -> List[Dict[str, Any]]:
        """获取插件信息"""
        if plugin_name:
            if plugin_name in self.plugins:
                return [self.plugins[plugin_name].get_info()]
            else:
                return []
        else:
            return [plugin.get_info() for plugin in self.plugins.values()]
    
    async def cleanup(self):
        """清理所有插件"""
        for plugin in self.plugins.values():
            try:
                await plugin.cleanup()
            except Exception as e:
                logger.error(f"清理插件失败 {plugin.name}: {e}")